﻿using HeWeatherAPI.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace HeWeatherAPI
{
    public class HeWeatherClient
    {
        private static HeWeatherClient instance;

        public static HeWeatherClient Instance
        {
            get
            {
                if (instance == null)
                {
                    var current = new HeWeatherClient();
                    System.Threading.Interlocked.CompareExchange(ref instance, current, null);
                }

                return instance;
            }
        }

        private HeWeatherClient()
        {

        }

        public string QueryJson(string city)
        {
            Stream stream = null;
            StreamReader reader = null;
            try
            {
                string url = string.Format(Constants.RequestUrl, city, Constants.OAuthKey);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                stream = response.GetResponseStream();
                StringBuilder sb = new StringBuilder();
                reader = new StreamReader(stream, Encoding.UTF8);
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    sb.Append(line);
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }

        public HeWeatherResult Query(string city)
        {
            try
            {
                if (string.IsNullOrEmpty(city))
                {
                    return HeWeatherResult.Error;
                }

                string json = this.QueryJson(city);
                if (json == null)
                {
                    return HeWeatherResult.Error;
                }
                HeWeatherResult result = new HeWeatherResult();
                JObject o = JObject.Parse(json);
                IList<JToken> tokens = o[Constants.ServiceKey].Children().ToList();

                foreach (var item in tokens)
                {

                    HeWeather w = new HeWeather();
                    w.City = (string)item[Constants.BasicKey][Constants.CityKey];

                    IList<JToken> dailys = item[Constants.DailyForcastKey].Children().ToList();
                    foreach (var daily in dailys)
                    {
                        DailyForcast df = new DailyForcast();
                        df.Condition = (string)daily[Constants.ConditionKey][Constants.TxtdKey];
                        df.MaxTemperature = (float)daily[Constants.TemperatureKey][Constants.MaxKey];
                        df.MinTemperature = (float)daily[Constants.TemperatureKey][Constants.MinKey];
                        df.Date = (DateTime)daily[Constants.DateKey];
                        w.DailyForcasts.Add(df);
                    }

                    IList<JToken> hourlys = item[Constants.HourlyForcastKey].Children().ToList();
                    foreach (var hourly in hourlys)
                    {
                        HourlyForcast hf = new HourlyForcast();
                        hf.Time = (DateTime)hourly[Constants.DateKey];
                        hf.Temperature = (float)hourly[Constants.TemperatureKey];
                        w.HourlyForcasts.Add(hf);
                    }

                    w.Status = (string)item[Constants.StatusKey];

                    JToken now = item[Constants.NowKey];
                    Weather current = new Weather();
                    current.Condition = (string)now[Constants.ConditionKey][Constants.TxtKey];
                    current.Temperature = (float)now[Constants.TemperatureKey];
                    current.City = w.City;
                    w.Current = current;

                    result.Weather.Add(w);
                }

                return result;

            }
            catch (Exception ex)
            {
                Console.WriteLine("error:{0}", ex.StackTrace);
            }
            return HeWeatherResult.Error;
        }
    }
}
